//
//  AVAudioEngineController.m
//  AudioKitOC
//
//  Created by youloft on 2018/5/4.
//  Copyright © 2018年 AudioKit. All rights reserved.
//

#import "AVAudioEngineController.h"
#import <AVFoundation/AVFoundation.h>

@interface AVAudioEngineController () {
    AVAudioEngine           *_engine;
    AVAudioUnitReverb       *_reverb;
    AVAudioPlayerNode       *_player;
    AVAudioPCMBuffer        *_playerLoopBuffer;
    NSURL                   *_mixerOutputFileURL;
}


@property (weak, nonatomic) IBOutlet UILabel *currentReverb;

@end

@implementation AVAudioEngineController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self initAndCreateNodes];
    [self createEngineAndAttachNodes];
    [self makeEngineConnections];
    [self setNodeDefaults];
}

- (void)initAndCreateNodes
{
    NSError *error;
    BOOL success = NO;
    _engine = nil;
    _reverb = nil;
    _player = nil;
    _player = [[AVAudioPlayerNode alloc] init];
    _reverb = [[AVAudioUnitReverb alloc] init];
    NSURL *drumLoopURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"追光者" ofType:@"mp3"]];
    AVAudioFile *drumLoopFile = [[AVAudioFile alloc] initForReading:drumLoopURL error:&error];
    _playerLoopBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:[drumLoopFile processingFormat] frameCapacity:(AVAudioFrameCount)[drumLoopFile length]];
    success = [drumLoopFile readIntoBuffer:_playerLoopBuffer error:&error];
    
    NSAssert(success, @"couldn't read drumLoopFile into buffer, %@", [error localizedDescription]);
}

- (void)createEngineAndAttachNodes {
    _engine = [[AVAudioEngine alloc] init];
    [_engine attachNode:_reverb];
    [_engine attachNode:_player];
}

- (void)makeEngineConnections
{
    AVAudioMixerNode *mainMixer = [_engine mainMixerNode];
    AVAudioFormat *playerFormat = _playerLoopBuffer.format;
    [_engine connect:_player to:_reverb format:playerFormat];
    [_engine connect:_reverb to:mainMixer fromBus:0 toBus:0 format:playerFormat];

}

- (void)setNodeDefaults
{
    _reverb.wetDryMix = 10;
    [_reverb loadFactoryPreset:AVAudioUnitReverbPresetMediumHall];
}

- (void)startEngine
{
    if (!_engine.isRunning) {
        NSError *error;
        BOOL success;
        success = [_engine startAndReturnError:&error];
        NSAssert(success, @"couldn't start engine, %@", [error localizedDescription]);
        NSLog(@"Started Engine");
    }
}

- (void)startRecordingMixerOutput
{
    NSError *error;
    if (!_mixerOutputFileURL) _mixerOutputFileURL = [NSURL URLWithString:[NSTemporaryDirectory() stringByAppendingString:@"mixerOutput.caf"]];
    
    AVAudioMixerNode *mainMixer = [_engine mainMixerNode];
    AVAudioFile *mixerOutputFile = [[AVAudioFile alloc] initForWriting:_mixerOutputFileURL settings:[[mainMixer outputFormatForBus:0] settings] error:&error];
    NSLog(@"%@", _mixerOutputFileURL);
    NSAssert(mixerOutputFile != nil, @"mixerOutputFile is nil, %@", [error localizedDescription]);
    
    [self startEngine];
    [mainMixer installTapOnBus:0 bufferSize:4096 format:[mainMixer outputFormatForBus:0] block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
        NSError *error;
        BOOL success = NO;
        success = [mixerOutputFile writeFromBuffer:buffer error:&error];
        NSAssert(success, @"error writing buffer data to file, %@", [error localizedDescription]);
    }];
}

- (void)stopRecordingMixerOutput
{
    [[_engine mainMixerNode] removeTapOnBus:0];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)play:(UIButton *)sender {
    [self startEngine];
    [_player scheduleBuffer:_playerLoopBuffer atTime:nil options:AVAudioPlayerNodeBufferInterrupts completionHandler:nil];
    [_player play];
}

- (IBAction)leftAdd:(id)sender {
    CGFloat pan = _player.pan - 0.1;
    if (pan < -1) {
        pan = -1;
    }
    _player.pan = pan;
}

- (IBAction)rightAdd:(id)sender {
    CGFloat pan = _player.pan + 0.1;
    if (pan > 1) {
        pan = 1;
    }
    _player.pan = pan;
}


- (IBAction)factory:(UIButton *)sender {
    /*
    AVAudioUnitReverbPresetSmallRoom       = 0,
    AVAudioUnitReverbPresetMediumRoom      = 1,
    AVAudioUnitReverbPresetLargeRoom       = 2,
    AVAudioUnitReverbPresetMediumHall      = 3,
    AVAudioUnitReverbPresetLargeHall       = 4,
    AVAudioUnitReverbPresetPlate           = 5,
    AVAudioUnitReverbPresetMediumChamber   = 6,
    AVAudioUnitReverbPresetLargeChamber    = 7,
    AVAudioUnitReverbPresetCathedral       = 8,
    AVAudioUnitReverbPresetLargeRoom2      = 9,
    AVAudioUnitReverbPresetMediumHall2     = 10,
    AVAudioUnitReverbPresetMediumHall3     = 11,
    AVAudioUnitReverbPresetLargeHall2      = 12
     */
    _currentReverb.text = sender.titleLabel.text;
    [_reverb loadFactoryPreset:sender.tag];
}


- (IBAction)volume:(UISlider *)sender {
    _player.volume = sender.value;
}

//干湿混合
- (IBAction)wetDryMix:(UISlider *)sender {
    _reverb.wetDryMix = sender.value;
}


- (IBAction)make:(UIButton *)sender {
    sender.selected = !sender.selected;
    if (sender.selected) {
        [self startRecordingMixerOutput];
    } else {
        [self stopRecordingMixerOutput];
    }
}



@end
